package neptune.web.server.services.experiment;

import it.robertobifulco.ias.UnauthorizedOperationException;
import it.robertobifulco.ias.rolemanager.RoleUndefinedException;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import neptune.manager.NeptuneManager;
import neptune.manager.validator.ValidatorResult;
import neptune.web.client.controller.DescriptorUploadController.UploadErrorCodes;
import neptune.web.client.services.SecurityException;
import neptune.web.client.view.components.TopologyPanel;
import neptune.web.server.ApplicationManager;
import neptune.web.server.Debug;
import neptune.web.server.InitializationException;
import neptune.web.server.operations.WriteTopologyFile;
import neptune.web.server.security.SecurityHelper;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

/**
 * Servlet implementation class for Servlet: TopologyFileHandler Gestisce il
 * caricammento di un file di topologia sul server
 * 
 */
public class TopologyFileHandler extends javax.servlet.http.HttpServlet
		implements javax.servlet.Servlet {
	static final long serialVersionUID = 1L;

	public static final String SEPARATOR_CHAR = "-R-s-t-S-e-p-";

	public static String TOPOLOGIES_DIRECTORY = "emuPlugin";

	/*
	 * (non-Java-doc)
	 * 
	 * @see javax.servlet.http.HttpServlet#HttpServlet()
	 */
	public TopologyFileHandler() {
		super();
	}

	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		try {
			TOPOLOGIES_DIRECTORY = ApplicationManager.getApplicationManager()
					.getConfigRepository().getTopologyRootDirectoryPath();
			if (!TOPOLOGIES_DIRECTORY.endsWith(File.separator)) {
				TOPOLOGIES_DIRECTORY += File.separator;
			}

			// Making directory hierarchy
			File dirHierarchy = new File(TOPOLOGIES_DIRECTORY);
			dirHierarchy.mkdirs();
		} catch (InitializationException e) {
			throw new ServletException(e);
		}
	}

	/*
	 * (non-Java-doc)
	 * 
	 * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request,
	 * HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
	}

	/*
	 * (non-Java-doc)
	 * 
	 * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request,
	 * HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		response.getWriter().println("<html><head></head><body></body></html>");

		boolean isMultipart = ServletFileUpload.isMultipartContent(request);

		// TODO controllare la creazione del file tramite IAS

		if (isMultipart) {
			// Create a factory for disk-based file items
			FileItemFactory factory = new DiskFileItemFactory();
			// Create a new file upload handler
			ServletFileUpload upload = new ServletFileUpload(factory);

			// Parse the request
			try {
				List<?> items = upload.parseRequest(request);

				// Recupero del nome dell'esperimento e del file dai campi del
				// form
				Iterator<?> iter = items.iterator();

				String expName = null;
				String xmlFileItemString = null;
				while (iter.hasNext()) {
					FileItem item = (FileItem) iter.next();
					if (item.getFieldName().equals(TopologyPanel.EXP_NAME))
						expName = item.getString();

					if (!item.isFormField()) {
						// Obtains file string
						xmlFileItemString = item.getString();
					}
				}
				// Verifica se ci sono tutte le informazioni
				if (expName == null || xmlFileItemString == null) {
					response.getWriter().print(
							UploadErrorCodes.EXCEPTION + SEPARATOR_CHAR
									+ "The received request is in bad format");
					return;
				}

				HttpSession session = request.getSession(false);
				WriteTopologyFile operation = (WriteTopologyFile) SecurityHelper
						.getOperation(WriteTopologyFile.ID, expName, session);

				Object[] args = new Object[] { xmlFileItemString, expName };

				try {
					ValidatorResult result = (ValidatorResult) operation
							.execute(args)[0];

					NeptuneManager manager = ApplicationManager
							.getApplicationManager().getNeptuneManager();
					response.getWriter().print(
							UploadErrorCodes.OK
									+ SEPARATOR_CHAR
									+ manager.getExperiment(expName).getState()
											.getValue() + SEPARATOR_CHAR
									+ result.getStatus() + SEPARATOR_CHAR
									+ result.getLog().prettyPrint(0));
				} catch (Exception e) {
					Debug.printTrace(e);
					response.getWriter().print(
							UploadErrorCodes.EXCEPTION + SEPARATOR_CHAR
									+ e.getMessage());
				}

			} catch (FileUploadException e) {
				Debug.printTrace(e);
				response.getWriter().print(
						UploadErrorCodes.EXCEPTION + SEPARATOR_CHAR
								+ e.getMessage());
			} catch (SecurityException e) {
				Debug.printTrace(e);
				response.getWriter().print(
						UploadErrorCodes.SECURITY_EXCEPTION + SEPARATOR_CHAR
								+ e.getMessage());
				e.printStackTrace();
			} catch (UnauthorizedOperationException e) {
				Debug.printTrace(e);
				response.getWriter().print(
						UploadErrorCodes.EXCEPTION + SEPARATOR_CHAR
								+ e.getMessage());
				e.printStackTrace();
			} catch (RoleUndefinedException e) {
				Debug.printTrace(e);
				response.getWriter().print(
						UploadErrorCodes.EXCEPTION + SEPARATOR_CHAR
								+ e.getMessage());
				e.printStackTrace();
			}
		} else {
			response.getWriter().print(
					UploadErrorCodes.EXCEPTION + SEPARATOR_CHAR
							+ "The received encoding format is not multipart");
		}
	}
}